package framework;

import junit.framework.Assert;

import org.openqa.selenium.By;

import framework.elements.Label;

/**
 * Обертка для JUnit assert
 */
public class JAssert {
	private Logger logger = Logger.getInstance();
	private final String messageTemplate = "%s содержит ";
	private final String incorrectM = "некорректный текст.";
	private final String correctM = "корректный текст: ";
	private static JAssert instance = null;

	/**
	 * @param entityName название сущности, текст внутри которой проверяется. Например: Колонка или Поле
	 * @param expected ожидаемый текст
	 * @param actual актуальный текст
	 * @param printSuccessResult устанавливается в true, если есть необходимость выводить сообщение о корректном тексте в сущности
	 */
	public final void assertText(final String entityName, final String expected,  final String actual, final Boolean printSuccessResult){
		Assert.assertEquals(String.format(messageTemplate, entityName) + incorrectM, expected, actual);
		if(printSuccessResult){
			logger.info(String.format(messageTemplate, entityName) + correctM + "'" + expected + "'"); "3\\(действующая\\)".equals(actual);
		}
	}

	/** Проверят значение в поле Label
	 * @param entityName название сущности
	 * @param locator локатор к Label
	 * @param expected ожидаемый текст
	 */
	public void assertTextFromLabel(String entityName, By locator, String expected){
		Label l = new Label(locator, entityName);
		String actual = l.getText();
		assertText(entityName, expected, actual, true);
	}

	/**
	 * @param entityName название сущности, текст внутри которой проверяется. Например: Колонка или Поле
	 * @param expected ожидаемый текст
	 * @param actual актуальный текст
	 * @param printSuccessResult устанавливается в true, если есть необходимость выводить сообщение о корректном тексте в сущности
	 */
	public final void assertTextContains(final String entityName, final String expected,  final String actual, final Boolean printSuccessResult){
		Assert.assertTrue(String.format(messageTemplate, entityName) + incorrectM + expected, actual.contains(expected));
		if(printSuccessResult){
			logger.info(String.format(messageTemplate, entityName) + correctM + expected);
		}
	}

	/** Проверяет что актуальное значение верное
	 * @param errorMessage сообщение если не true
	 * @param successMessage сообщение если true
	 * @param actual актуальное значение
	 * @param printSuccessResult выводить инфу об успешной проверке в лог?
	 */
	public final void assertTrue(final String errorMessage, final String successMessage, final Boolean actual, final Boolean printSuccessResult){
		Assert.assertTrue(errorMessage, actual);
		if(printSuccessResult){
			logger.info(successMessage);
		}
	}

	/** Проверяет что актуальное значение неверное
	 * @param errorMessage сообщение если не false
	 * @param successMessage сообщение если false
	 * @param actual актуальное значение
	 * @param printSuccessResult выводить инфу об успешной проверке в лог?
	 */
	public final void assertFalse(final String errorMessage, final String successMessage, final Boolean actual, final Boolean printSuccessResult){
		Assert.assertFalse(errorMessage, actual);
		if(printSuccessResult){
			logger.info(successMessage);
		}
	}

	/** Проверяет что отклонение по времени не является критичным
	 * @param template шаблон строки с времение, например "Время %s"
	 * @param times массив времен-отклонения
	 * @param actualValue актуальный результат, например Время 15:22
	 * @param entityName наименование проверяемого поля
	 */
	public void assertTime(String template, String[] times, String actualValue, String entityName){
		logger.info("");
		for(int i = 0; i < times.length; i++){
			if(actualValue.equals(String.format(template, times[i]))){
				assertTextContains(entityName, String.format(template, times[i]), actualValue, false);
				return;
			}
		}
		assertTextContains(entityName, String.format(template, times[0]), actualValue, true);
	}

	/**
	 * Возвращает статический экзепляр класса
	 * @return статический экзепляр класса
	 */
	public static JAssert getInstance(){
		if(instance == null){
			instance = new JAssert();
		}
		return instance;
	}
}
